/*
 * GeoVISTA Center (Penn State, Dept. of Geography)
 * Copyright (c), 2003-2011,  Jin Chen and Alan M. MacEachren, GeoVISTA Center, Penn State University
 * Licensed under Simplified BSD License
 *
 *
 * @author: jin Chen 
 * @date: Nov 28, 2005$
 * @version: 1.0
 */
package edu.psu.geovista.app.gmatrix.component;

import edu.psu.geovista.app.gmatrix.control.SelectClient;
import edu.psu.geovista.app.gmatrix.event.MatrixSelectionEvent;
import edu.psu.geovista.app.gmatrix.event.MatrixSelectionListener;
import edu.psu.geovista.app.gmatrix.toolkit.FireEventSupport;
import edu.psu.geovista.app.hce.clustering.model.BCluster;
import edu.psu.geovista.app.hce.dendroview.Demdrog3;
import edu.psu.geovista.app.vit.pub.utils.VitUtils;

import javax.swing.*;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;

public class DendroMatrixHeader extends Demdrog3 implements MatrixHeader, MatrixSelectionListener {
    private static final Logger logger=Logger.getLogger(DendroMatrixHeader.class.getName());
    String[] celllabels;//
    SelectClient selectClient;//any selection outcome will be passed outside via this interface
    private FireEventSupport evtfirer;
    //JPanel foot;
    MatrixHeader leafheader;
    public DendroMatrixHeader(int i) {
        super(i);
        addBarListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                Set ids = (Set) evt.getNewValue();
                int[] selects = VitUtils.convert2IntArray(ids);
                //selectRow(rows,true);//need fire event
                fireBarSelection(selects);//a element of the array can be row/col index, depend on orient

            }
        } );

    }
    public  void ban(int curselect){
        ((BannableMatrixHeader)leafheader).ban(curselect);
    }
     public  void ban(int[] indexs){
        ((BannableMatrixHeader)leafheader).ban(indexs);
    }
    public  void unban(int curselect){
        ((BannableMatrixHeader)leafheader).unban(curselect);

    }
    public  void unban(int[] indexs){
         ((BannableMatrixHeader)leafheader).unban(indexs);
    }
     public void unbanAll(){
          ((BannableMatrixHeader)leafheader).unbanAll();
     }
     protected  void init() {
         super.init();

         leafheader = (MatrixHeader) setupfoot();
         this.add((Component) this.leafheader);
         layoutFoot();


     }

    public void setInfo(BCluster rnode, java.util.List lfs, java.util.List clsts,int nbcls,int nblfcls,double min, double max, String[] leafIds){
        super.setInfo(rnode,lfs,clsts,nbcls,nblfcls,min,max);
        if(leafIds!=null){
            
             leafheader.setCelllabels(leafIds);


         }
    }



    private MatrixHeader setupfoot() {
        int width = this.sizes.getFootoffset().width;
        int orient = this.getOrient();
        int footOrient = getFootOrient(orient);
        DfMatrixHeader  foot=new BannableMatrixHeader(width,footOrient);
        return foot;
    }

    private int getFootOrient(int orient) {
        int myorient= SwingConstants.HORIZONTAL ;
        if(orient ==SwingConstants.SOUTH ||orient ==SwingConstants.NORTH ){
             myorient=SwingConstants.HORIZONTAL ;
        }
        else if (orient ==SwingConstants.EAST ||orient ==SwingConstants.WEST ){
            myorient=SwingConstants.VERTICAL ;
        }
        return myorient;
    }

    protected void setsizes(Dimension compSize){
        super.setsizes(compSize);
        layoutFoot();
    }

    private void layoutFoot() {
        if(sizes==null)return;
         int orient = this.getOrient();
        int footOrient = getFootOrient(orient);
       // this.foot.setOrient(footOrient);
        Rectangle bd = this.sizes.getFootBound(this.getOrient());
       
        ((JComponent)leafheader).setBounds(bd);
    }

   public void setOrient(int orient) {
       super.setOrient(orient);
       layoutFoot();
       this.revalidate();
       this.repaint();
   }


    public double[] getCellcenters() {
        return new double[0];//todo not yet
    }

    public void setCellcenters(double[] cellcenters) {
        leafheader.setCellcenters(cellcenters);
        this.setLeafsInterval(cellcenters);//todo, seems  conceptually, LeafsInterval!=  cellcenters
    }

    public String[] getCelllabels() {
        return celllabels;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public void setCelllabels(String[] celllabels) {
        this.celllabels = celllabels;
        this.leafheader.setCelllabels(celllabels);
    }

    public void setCellrender(JLabel cellrender) {

    }

    public JLabel getCellrender() {
        //super.getCe
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    public void setSelectclient(SelectClient selectclient) {
        this.selectClient = selectclient;
        this.leafheader.setSelectclient(selectclient);
    }

    public void setSelection(int[] select) {
        this.leafheader.setSelection(select);
        //this.repaint();
    }

    public MatrixHeader getLeafheader() {
        return leafheader;
    }

    public void setLeafheader(MatrixHeader leafheader) {
        this.leafheader = leafheader;
    }
    /*******************************************************************************************************
     *                selection
     *******************************************************************************************************/
    /**
     * react on external selection
     * @param e
     */
    public void matrixSelectionChanged(MatrixSelectionEvent e) {
        //todo, do selection on the header, but not fire selection event.
    }
     /**************************************************
      *        register to listen my selection
      ***************************************************/
     /**
     *
     * @param l
     */
    public void addMatrixSelectionChangeListener(MatrixSelectionListener l){
        this.getEvtfirer().addListener(MatrixSelectionListener.class, l);
    }

    /**
     * usally fire selection made by the bar, ignore those been banned by foot
     * @param selects
     */
    protected void fireBarSelection(int[] selects){
        int orient = this.getOrient();
        Set <Integer> barselects=new HashSet<Integer>(selects.length );
        for (int i=0;i<selects.length ;i++){
            barselects.add(selects[i]); 
        }
        Set<Integer> bannedIndexs = ((BannableMatrixHeader) this.leafheader).getBannedIndexs();

        barselects.removeAll(bannedIndexs);
        if(barselects.size() ==0)return;

        int[] finalSelects = VitUtils.convert2IntArray(barselects);

        if(orient==SwingConstants.SOUTH ||orient==SwingConstants.NORTH ){
              //this.getEvtfirer().fireSelectColumnChanged(finalSelects);
              selectClient.selectColumn(finalSelects);
        }
        else if (orient==SwingConstants.WEST ||orient==SwingConstants.EAST ){
             selectClient.selectRow(finalSelects);
            // this.getEvtfirer().fireSelectRowChanged(finalSelects, MatrixSelectionEvent.SELECT_ROW);
        }
        else{
            System.err.println(this+" unable to process.");
        }

    }
     public FireEventSupport getEvtfirer() {
        if(evtfirer==null){
            evtfirer=new FireEventSupport(this);
        }
        return evtfirer;
    }

    /*******************************************************************************************************
     *                action
     *******************************************************************************************************/
    


}
